package com.cx.cxapi;


import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.jws.thirdlibrary.CxManager;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class CanActivity extends Activity implements View.OnClickListener {

    private final static String TAG = "CANBUS";
    private static final String FILE_PATH = "/storage/emulated/0/Documents";
    private static final String FILE_NAME = "CAN_received_data.txt";
    private static final File mFile = new File(FILE_PATH, FILE_NAME);
    private Button btn_send;
    private Button btn_clear;
    private EditText et_send_id;
    private EditText et_send_length;
    private EditText et_send_eff;
    private EditText et_send_rtr;
    private EditText et_send_data;
    private Button btn_query_network_device;
    private TextView tv_query_result;
    private Button btn_show_can_information;
    private TextView tv_show_can_information;
    private Button btn_close_can;
    private Button btn_open_can;
    private Button btn_open_can_loopback;
    private EditText et_bitrate;
    private EditText et_loopback_bitrate;
    private TextView tv_received_data;
    private CxManager mCxManager;
    private Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_can);
        btn_send = findViewById(R.id.btn_send);
        btn_clear = findViewById(R.id.btn_clear);
        et_send_id = findViewById(R.id.et_send_id);
        et_send_length = findViewById(R.id.et_send_length);
        et_send_eff = findViewById(R.id.et_send_eff);
        et_send_rtr = findViewById(R.id.et_send_rtr);
        et_send_data = findViewById(R.id.et_send_data);
        btn_query_network_device = findViewById(R.id.btn_query_network_device);
        tv_query_result = findViewById(R.id.tv_query_result);
        btn_show_can_information = findViewById(R.id.btn_show_can_information);
        tv_show_can_information = findViewById(R.id.tv_show_can_information);
        btn_close_can = findViewById(R.id.btn_close_can);
        btn_open_can = findViewById(R.id.btn_open_can);
        et_bitrate = findViewById(R.id.et_bitrate);
        btn_open_can_loopback = findViewById(R.id.btn_open_can_loopback);
        et_loopback_bitrate = findViewById(R.id.et_loopback_bitrate);
        tv_received_data = findViewById(R.id.tv_received_data);

        btn_send.setOnClickListener(this);
        btn_clear.setOnClickListener(this);
        btn_query_network_device.setOnClickListener(this);
        btn_show_can_information.setOnClickListener(this);
        btn_close_can.setOnClickListener(this);
        btn_open_can.setOnClickListener(this);
        btn_open_can_loopback.setOnClickListener(this);
        mCxManager = CxManager.create(this);
        mContext = this;
        if (mFile.exists()) {
            mFile.delete();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(CxManager.ACTION_CAN_RECEIVED_DATA);
        registerReceiver(mCanReceivedDateReceiver, intentFilter);
        Log.i(TAG, "onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mCanReceivedDateReceiver != null) {
            unregisterReceiver(mCanReceivedDateReceiver);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCxManager.jwsCloseCan();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_send:
                String ID = et_send_id.getText().toString();
                String sendLength = et_send_length.getText().toString();
                String sendData = et_send_data.getText().toString();
                String sendEFF = et_send_eff.getText().toString();
                String sendRTR = et_send_rtr.getText().toString();
                if (ID == null || ID.length() == 0 || sendEFF.length() == 0 || sendEFF == null
                        || sendRTR.length() == 0 || sendRTR == null || sendLength == null || sendLength.length() == 0
                        || sendData == null || sendData.length() == 0 || !isNumeric(ID) || !isNumeric(sendEFF)
                        || !isNumeric(sendRTR) || !isNumeric(sendLength)) {
                    Toast.makeText(mContext, getString(R.string.str_send_data_invalid), Toast.LENGTH_SHORT).show();
                    return;
                }

                String strDataArr[] = sendData.replace(" ", "").split(",");
                int ret = mCxManager.jwsCanSendData(Long.parseLong(ID), Integer.parseInt(sendEFF), Integer.parseInt(sendRTR), Integer.parseInt(sendLength), strDataArr);

                Log.i(TAG, "ret = " + ret);
                if (ret <= 0) {
                    Log.i(TAG, "Send data failed!");
                } else {
                    Log.i(TAG, "Send data successfully!");
                }
                break;
            case R.id.btn_clear:
                tv_received_data.setText("");
                if (mFile.exists()) {
                    mFile.delete();
                }
                break;
            case R.id.btn_query_network_device:
                String strQueryResult = mCxManager.jwsQueryNetworkDevice();
                tv_query_result.setText(strQueryResult);
                break;
            case R.id.btn_show_can_information:
                String strCanInfo = mCxManager.jwsShowCanInformation();
                tv_show_can_information.setText(strCanInfo);
                break;
            case R.id.btn_close_can:
                mCxManager.jwsCloseCan();
                break;
            case R.id.btn_open_can:
                String strBitrate = et_bitrate.getText().toString();
                if (strBitrate != null && strBitrate.length() != 0) {
                    int bitrate = Integer.parseInt(strBitrate);
                    boolean flagOpenCan = mCxManager.jwsOpenCan(bitrate);
                    if (flagOpenCan) {
                        Toast.makeText(mContext, "Open CAN successfully!", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(mContext, "Open CAN failed!", Toast.LENGTH_SHORT).show();
                    }
                }

                break;
            case R.id.btn_open_can_loopback:
                String strLoopbackBitrate = et_loopback_bitrate.getText().toString();
                if (strLoopbackBitrate != null && strLoopbackBitrate.length() != 0) {
                    int bitrate = Integer.parseInt(strLoopbackBitrate);
                    boolean flagOpenLoopbackCan = mCxManager.jwsOpenCanLoopBack(bitrate);
                    if (flagOpenLoopbackCan) {
                        Toast.makeText(mContext, "Open CAN loopback mode successfully!", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(mContext, "Open CAN loopback mode failed!", Toast.LENGTH_SHORT).show();
                    }
                }

                break;
        }
    }

    BroadcastReceiver mCanReceivedDateReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.i(TAG, "onReceive: action " + action);
            long canID = intent.getLongExtra("id", 0);
            int length = intent.getIntExtra("Length", 0);
            int eff = intent.getIntExtra("eff", 0);
            int rtr = intent.getIntExtra("rtr", 0);

            String str = "can0" + " " + "0x" + Long.toHexString(canID).toUpperCase() + " " + eff + " " + rtr + " [" + length + "] ";
            if (rtr == 1) {
                String[] receivedDataArr = new String[1];
                receivedDataArr = intent.getStringArrayExtra("receivedData");
                str = str + receivedDataArr[0] + " ";
            } else {
                for (int i = 0; i < length; i++) {
                    String[] receivedDataArr = new String[length];
                    receivedDataArr = intent.getStringArrayExtra("receivedData");
                    Log.i(TAG, "receivedDataArr[i] = " + receivedDataArr[i]);
                    str = str + receivedDataArr[i] + " ";
                }
            }
            str += "\n";
            writeFile(str);
            if (tv_received_data.getLineCount() > 20) {
                tv_received_data.setText("");
            }
            Log.i(TAG, "str = " + str);
            tv_received_data.append(str);
        }
    };

    public static boolean isNumeric(String str) {
        for (int i = str.length(); --i >= 0; ) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }


    public void writeFile(String content) {
        try {
            File fileDir = new File(FILE_PATH);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
                if (!fileDir.exists()) {
                    return;
                }
            }

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(mFile, true), "utf-8"));
            out.write(content);
//            out.newLine();
            out.flush();
            out.close();
            fileSync();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void fileSync() {
        Runtime runtime = Runtime.getRuntime();
        try {
            runtime.exec("sync");
            Log.e(TAG, "fileSync successfully!");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "fileSync Exception: " + e.getMessage());
        }
    }
}